import { Author } from "../../entities/Author";
import { Book } from "../../entities/Book";
import { initORM } from "../../utils";
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next";

type Data = {
  name: string;
  books: any;
};

async function getBooks(req: NextApiRequest, res: NextApiResponse<any>) {
  const em = await initORM();
  // const books = await em.findAll(Book, {});
  const books = await em.findAll("Book", {}); // same as above
  res.status(200).json({ books });
}

async function createBook(req: NextApiRequest, res: NextApiResponse<any>) {
  const em = await initORM();
  const data = req.body || {};

  // 1. will extract necessary params from `data` to create new book object
  // const book = em.create(Book, data);
  // await em.persist(book).flush();

  // 2. use entity name is also ok
  // const book = em.create("Book", data);
  // await em.persist(book).flush();

  // 3. new Book and persist it, ERROR
  // const book = new Book(data.title);
  // await em.persistAndFlush(book);

  // 4. create book, and setup author
  const book = em.create(Book, data);
  const author = em.getReference(Author, data.author_id, { wrapped: true });
  book.author = author;
  //   console.log("🚀 ~ createBook ~ book:", book);

  await em.persistAndFlush(book);

  res.status(200).json({ book });
}

async function updateBook(req: NextApiRequest, res: NextApiResponse<any>) {
  const em = await initORM();
  const data = req.body || {};
  const book = await em.findOne(Book, data.id);
  if (!book) {
    res.status(404).json({ error: "Book not found" });
  } else {
    book.title = data.title;
    await em.persistAndFlush(book);
    res.status(200).json({ book });
  }
}

async function deleteBook(req: NextApiRequest, res: NextApiResponse<any>) {
  const em = await initORM();
  const data = req.body || {};
  const book = await em.findOne(Book, data.id);
  if (!book) {
    res.status(404).json({ error: "Book not found" });
  } else {
    await em.removeAndFlush(book);
    res.status(200).json({ book });
  }
}

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse<any>
) {
  if (req.method === "GET") {
    return getBooks(req, res);
  } else if (req.method === "POST") {
    return createBook(req, res);
  } else if (req.method === "PUT") {
    return updateBook(req, res);
  } else if (req.method === "DELETE") {
    return deleteBook(req, res);
  }
}
